package com.sskj.trafficcontrol.util;

import com.sskj.trafficcontrol.consts.AppRequestConsts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class RequestUtil {
    /**
     * 取得客户端ip地址<br>
     * 如果用户使用了代理，则也只返回其真实IP
     *
     * @param request HttpServletRequest
     * @return
     */
    public static String getClientIp(HttpServletRequest request) {
        // 如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串ip值，客户端真实的ip是：第一个非unknown的有效IP字符串
        String ip = request.getHeader("X-Forwarded-For");// X-Forwarded-For: client1, proxy1, proxy2
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
//        X-Forwarded-For一般格式如下:其中的值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求，就把请求来源IP地址添加到右边。
//        X-Forwarded-For: client1, proxy1, proxy2, proxy3
        int multIpFirstSplitIndex = ip.indexOf(",");
        if (multIpFirstSplitIndex != -1) {
            ip = ip.substring(0, multIpFirstSplitIndex);
        }
        if (ip.length() > 15) {
            // IPv4最长15位
            ip = ip.substring(0, 15);
        }
        return ip;
    }

    /**
     * 得到完成的app Url地址
     * <p/>
     * 一定不以/结尾
     *
     * @param request
     * @return
     */
    public static String getAppUrl(HttpServletRequest request) {
        StringBuilder url = new StringBuilder();
        int port = request.getServerPort();
        if (port < 0) {
            port = 80;
            // Work around java.net.URL bug
        }
        String scheme = request.getScheme().toLowerCase();
        url.append(scheme);
        url.append("://");
        url.append(request.getServerName());
        if ((scheme.equals("http") && (port != 80))
                || (scheme.equals("https") && (port != 443))) {
            url.append(':');
            url.append(port);
        }
        url.append(request.getContextPath());
        return url.toString();
    }

    /**
     * 获取当前登录用户的userId。在com.lswuyou.api.web.controller.auth以下的Controller中调用，一定不会返回null，无需验证
     */
    public static Long getRequestUserId(HttpServletRequest request) {
        return (Long) request.getAttribute(AppRequestConsts.ATTR_USER_ID);
    }

    /**
     * 获取当前登录用户的AppUserInfo。在com.lswuyou.api.web.controller.auth以下的Controller中调用，一定不会返回null，无需验证
     */
   /* public static AppUserInfo getRequestUser(HttpServletRequest request) {
        return (AppUserInfo) request.getAttribute(AppRequestConsts.ATTR_USER);
    }*/

    /**
     * 获取当前登录用户的userKey。在com.lswuyou.api.web.controller.auth以下的Controller中调用，一定不会返回null，无需验证
     */
    public static String getRequestUserToken(HttpServletRequest request) {
        return (String) request.getAttribute(AppRequestConsts.ATTR_USER_TOKEN);
    }

    /**
     * 获取当前请求的平台。在Controller中调用，一定不会返回null，无需验证
     */
    public static Integer getRequestPlatform(HttpServletRequest request) {
        return (Integer) request.getAttribute(AppRequestConsts.ATTR_PLATFORM);
    }

    /**
     * 获取当前请求的客户端平台是否是IOS
     */
   /* public static boolean isRequestPlatformIos(HttpServletRequest request) {
        return AppUserDevicePlatform.iOS.val.equals(getRequestPlatform(request).intValue());
    }*/

    /**
     * 获取当前请求的客户端平台是否是Android
     */
    /*public static boolean isRequestPlatformAndroid(HttpServletRequest request) {
        return AppUserDevicePlatform.android.val.equals(getRequestPlatform(request).intValue());
    }*/

    /**
     * 获取当前请求所使用的客户端版本。在Controller中调用，一定不会返回null，无需验证
     */
    public static String getRequestVersion(HttpServletRequest request) {
        return (String) request.getAttribute(AppRequestConsts.ATTR_VERSION);
    }

    /**
     * 获取当前请求所使用的客户端版本。在Controller中调用，一定不会返回null，无需验证
     * 返回去掉“.”的int类型，如：2.0.0-->200;2.0.1-->201
     */
    public static int getRequestVersionInt(HttpServletRequest request) {
        String versionStr = (String) request.getAttribute(AppRequestConsts.ATTR_VERSION);
        versionStr = versionStr.replace(".", "").trim();
        return Integer.parseInt(versionStr);
    }
    /**
     * 为了避免requestUri与数据库不匹配，此方法会把多条/替换成一条/
     * <p/>
     * 而且一定不会返回contextPath
     *
     * @param request
     * @return
     */
    public static String getFixedRequestUri(HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        String contextPath = request.getContextPath();
        return getFixedRequestUri(requestUri, contextPath);
    }

    /**
     * 为了避免requestUri与数据库不匹配，此方法会把多条/替换成一条/
     * <p/>
     * 而且一定不会返回contextPath
     *
     * @param requestUri
     * @return
     */
    public static String getFixedRequestUri(String requestUri, String contextPath) {
        String requestUriLower = requestUri.toLowerCase();
        if (requestUriLower.startsWith("http://")) {
            requestUri = requestUri.substring(requestUriLower.indexOf("/", requestUriLower.indexOf("http://") + "http://".length()));
        } else if (requestUriLower.startsWith("https://")) {
            requestUri = requestUri.substring(requestUriLower.indexOf("/", requestUriLower.indexOf("https://") + "https://".length()));
        }
        while (requestUri.contains("//")) {
            requestUri = requestUri.replace("//", "/");
        }
        if (contextPath != null && contextPath.length() > 0) {
            requestUri = requestUri.substring(requestUri.indexOf(contextPath) + contextPath.length());
        }
        return requestUri;
    }
    /**
     * @param request
     * @param response
     * @param httpStatusCode HTTP状态码；如200, 404, 500
     * @param errorJson
     */
    public static void sendErrorJsonResponse(HttpServletRequest request, HttpServletResponse response,
                                             int httpStatusCode, String errorJson) {
        Logger logger = LoggerFactory.getLogger(RequestUtil.class);
        String charSet = request.getCharacterEncoding();
        String contentType = AppRequestConsts.CONTENT_TYPE_JSON;
        // 在响应头中声明，响应内容采用明文方式
        response.setCharacterEncoding(charSet);
        response.setContentType(contentType);
        response.setStatus(httpStatusCode);
        response.setHeader("Access-Control-Allow-Origin","*");//解决跨越问题
        PrintWriter out = null;

        try {
            out = response.getWriter();
            out.print(errorJson);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null) {
                out.close();
            }
        }
    }


}
